package pinboard.dataLayer.binPack;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;

class PackAttributeCache {
    HashMap<Class<?>, List<PackAttributeFormat>> cache = new HashMap<>();

    Comparator comparator;

    public PackAttributeCache() {
        comparator = new Comparator<PackAttributeFormat>() {
            @Override
            public int compare(PackAttributeFormat binMarkFormat, PackAttributeFormat t1) {
                return binMarkFormat.seqNo - t1.seqNo;
            }
        };
    }

    public List<PackAttributeFormat> get(Class<?> tClass) {
        if (!cache.containsKey(tClass)) {
            ArrayList<PackAttributeFormat> list = new ArrayList<>();
            Field[] fields = tClass.getFields();
            for (Field f : fields) {
                PackAttribute mark = f.getAnnotation(PackAttribute.class);
                if (mark == null) {
                    continue;
                }
                PackAttributeFormat bmf = new PackAttributeFormat();
                bmf.fieldType = f.getType();
                bmf.fieldGenericType = f.getGenericType();
                bmf.fieldName = f.getName();
                bmf.seqNo = mark.seqNo();
                bmf.serializerName = mark.serializerName();
                bmf.fixedRange = mark.fixedRange();
                Class<?> ft = f.getType();

                if (ft.isArray()) {
                    bmf.isGroup = true;
                } else if (List.class.isAssignableFrom(ft)) {
                    bmf.isGroup = true;
                }

                list.add(bmf);
            }
            Collections.sort(list, comparator);
            cache.put(tClass, list);
        }
        return cache.get(tClass);
    }
}
